package frame.core;

import frame.pojo.Configuration;

import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * FileName: SqlSessionImpl
 * Author:   xuan zongjun
 * Date:     2020/11/4 11:13
 * Description: 框架对外接口的实现类
 */


public class SqlSessionImpl implements SqlSession {
    // TODO 待办事项
   private Configuration configuration;
   public void setConfiguration(Configuration configuration){
       this.configuration = configuration;

   }


    public <T> List<T> selectList(String sqlId) throws Exception {
        List<T> list = new ArrayList<>();

        Class.forName( configuration.getDriver() );
        Connection connection = DriverManager.getConnection( configuration.getUrl(), configuration.getUsername(), configuration.getPassword() );

        // TODO 待办事项
        String sql=configuration.getMapperMap().get( sqlId ).getSql();
        PreparedStatement preparedStatement = connection.prepareStatement( sql );
        ResultSet resultSet = preparedStatement.executeQuery();

        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();


        List<String> columnLabels = new ArrayList<>();
        for (int i = 0; i < columnCount; i++) {
            columnLabels.add( metaData.getColumnLabel( i ) );
        }

        // 需要知道结果集实体Pojo的全限定类名，比如:com.mybatis.pojo.User，然后使用反射技术处理
        // TODO 待办事项
        String resultType = configuration.getMapperMap().get( sqlId ).getResultType();
        Class aClass = Class.forName(resultType);

        Method[] methods = aClass.getMethods();
        // 取代User user = null;

        Object obj = null;
        while (resultSet.next()){
            // 取代user = new User();
            obj = aClass.newInstance();
            // 取代user.setUsername(resultSet.getString("username"));
            for (String columnLabel : columnLabels) {
                for (Method method : methods) {
                    if(method.getName().equalsIgnoreCase( "set"+columnLabel )){
                        method.invoke( obj,resultSet.getObject( columnLabel ));
                    }
                }
                list.add( (T)obj );
            }
        }

        resultSet.close();
        preparedStatement.close();
        connection.close();


        return list;
    }
}
